package cn.isgrow.gateway.service;

import cn.isgrow.gateway.entity.RouteDefinitionEntity;
import cn.isgrow.gateway.repository.IMongoRouteDefinitionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author Itachi is.xianglei@gmail.com
 * @Date 2020-05-22 22:00
 */
@Service
public class MongoDynamicRouteService implements ApplicationEventPublisherAware {

    @Autowired private IMongoRouteDefinitionRepository mongoRouteDefinitionRepository;

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 增加路由
     * @param entity
     * @return
     */
    public Mono<RouteDefinitionEntity> add(RouteDefinitionEntity entity) {
        Mono<RouteDefinitionEntity> saveEntity = mongoRouteDefinitionRepository.save(entity);
        applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return saveEntity;
    }

    /**
     * 更新
     * @param entity
     * @return
     */
    public Mono<RouteDefinitionEntity> update(RouteDefinitionEntity entity) {
        Mono<RouteDefinitionEntity> saveEntity= mongoRouteDefinitionRepository.save(entity);
        applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return saveEntity;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    public Mono<ResponseEntity<Void>> deleteById(String id) {
        return mongoRouteDefinitionRepository.findById(id)
                //当你需要操作数据并返回一个mono使用flatmap
                // 如果不操作数据仅作转换数据，使用map
                .flatMap(entity -> mongoRouteDefinitionRepository.delete(entity))
        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
        .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
    }

    /**
     * 查询所有路由
     * @param
     * @return
     */
    public Flux<RouteDefinitionEntity> findAll() {
        return mongoRouteDefinitionRepository.findAll();
    }

    public Mono<RouteDefinitionEntity> findById(String id) {
        return mongoRouteDefinitionRepository.findById(id);
    }

    public Mono<Void> refresh() {
        applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return Mono.empty();
    }
}
